
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" lang="zh_Hans">
  <head>
    <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>Asynchronous support &#8212; Django 3.2.6.dev 文档</title>
    <link rel="stylesheet" href="../_static/default.css" type="text/css" />
    <link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
    <script type="text/javascript" id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
    <script type="text/javascript" src="../_static/jquery.js"></script>
    <script type="text/javascript" src="../_static/underscore.js"></script>
    <script type="text/javascript" src="../_static/doctools.js"></script>
    <script type="text/javascript" src="../_static/language_data.js"></script>
    <link rel="index" title="索引" href="../genindex.html" />
    <link rel="search" title="搜索" href="../search.html" />
    <link rel="next" title="操作指南" href="../howto/index.html" />
    <link rel="prev" title="External packages" href="external-packages.html" />



 
<script src="../templatebuiltins.js"></script>
<script>
(function($) {
    if (!django_template_builtins) {
       // templatebuiltins.js missing, do nothing.
       return;
    }
    $(document).ready(function() {
        // Hyperlink Django template tags and filters
        var base = "../ref/templates/builtins.html";
        if (base == "#") {
            // Special case for builtins.html itself
            base = "";
        }
        // Tags are keywords, class '.k'
        $("div.highlight\\-html\\+django span.k").each(function(i, elem) {
             var tagname = $(elem).text();
             if ($.inArray(tagname, django_template_builtins.ttags) != -1) {
                 var fragment = tagname.replace(/_/, '-');
                 $(elem).html("<a href='" + base + "#" + fragment + "'>" + tagname + "</a>");
             }
        });
        // Filters are functions, class '.nf'
        $("div.highlight\\-html\\+django span.nf").each(function(i, elem) {
             var filtername = $(elem).text();
             if ($.inArray(filtername, django_template_builtins.tfilters) != -1) {
                 var fragment = filtername.replace(/_/, '-');
                 $(elem).html("<a href='" + base + "#" + fragment + "'>" + filtername + "</a>");
             }
        });
    });
})(jQuery);</script>

  </head><body>

    <div class="document">
  <div id="custom-doc" class="yui-t6">
    <div id="hd">
      <h1><a href="../index.html">Django 3.2.6.dev 文档</a></h1>
      <div id="global-nav">
        <a title="Home page" href="../index.html">Home</a>  |
        <a title="Table of contents" href="../contents.html">Table of contents</a>  |
        <a title="Global index" href="../genindex.html">Index</a>  |
        <a title="Module index" href="../py-modindex.html">Modules</a>
      </div>
      <div class="nav">
    &laquo; <a href="external-packages.html" title="External packages">previous</a>
     |
    <a href="index.html" title="Using Django" accesskey="U">up</a>
   |
    <a href="../howto/index.html" title="操作指南">next</a> &raquo;</div>
    </div>

    <div id="bd">
      <div id="yui-main">
        <div class="yui-b">
          <div class="yui-g" id="topics-async">
            
  <div class="section" id="s-asynchronous-support">
<span id="asynchronous-support"></span><h1>Asynchronous support<a class="headerlink" href="#asynchronous-support" title="永久链接至标题">¶</a></h1>
<p>Django has support for writing asynchronous (&quot;async&quot;) views, along with an
entirely async-enabled request stack if you are running under
<a class="reference internal" href="../howto/deployment/asgi/index.html"><span class="doc">ASGI</span></a>. Async views will still work under
WSGI, but with performance penalties, and without the ability to have efficient
long-running requests.</p>
<p>We're still working on async support for the ORM and other parts of Django.
You can expect to see this in future releases. For now, you can use the
<a class="reference internal" href="#asgiref.sync.sync_to_async" title="asgiref.sync.sync_to_async"><code class="xref py py-func docutils literal notranslate"><span class="pre">sync_to_async()</span></code></a> adapter to interact with the sync parts of Django.
There is also a whole range of async-native Python libraries that you can
integrate with.</p>
<div class="versionchanged">
<span class="title">Changed in Django 3.1:</span> <p>Support for async views was added.</p>
</div>
<div class="section" id="s-async-views">
<span id="async-views"></span><h2>Async views<a class="headerlink" href="#async-views" title="永久链接至标题">¶</a></h2>
<div class="versionadded">
<span class="title">New in Django 3.1.</span> </div>
<p>Any view can be declared async by making the callable part of it return a
coroutine - commonly, this is done using <code class="docutils literal notranslate"><span class="pre">async</span> <span class="pre">def</span></code>. For a function-based
view, this means declaring the whole view using <code class="docutils literal notranslate"><span class="pre">async</span> <span class="pre">def</span></code>. For a
class-based view, this means making its <code class="docutils literal notranslate"><span class="pre">__call__()</span></code> method an <code class="docutils literal notranslate"><span class="pre">async</span> <span class="pre">def</span></code>
(not its <code class="docutils literal notranslate"><span class="pre">__init__()</span></code> or <code class="docutils literal notranslate"><span class="pre">as_view()</span></code>).</p>
<div class="admonition note">
<p class="first admonition-title">注解</p>
<p class="last">Django uses <code class="docutils literal notranslate"><span class="pre">asyncio.iscoroutinefunction</span></code> to test if your view is
asynchronous or not. If you implement your own method of returning a
coroutine, ensure you set the <code class="docutils literal notranslate"><span class="pre">_is_coroutine</span></code> attribute of the view
to <code class="docutils literal notranslate"><span class="pre">asyncio.coroutines._is_coroutine</span></code> so this function returns <code class="docutils literal notranslate"><span class="pre">True</span></code>.</p>
</div>
<p>Under a WSGI server, async views will run in their own, one-off event loop.
This means you can use async features, like concurrent async HTTP requests,
without any issues, but you will not get the benefits of an async stack.</p>
<p>The main benefits are the ability to service hundreds of connections without
using Python threads. This allows you to use slow streaming, long-polling, and
other exciting response types.</p>
<p>If you want to use these, you will need to deploy Django using
<a class="reference internal" href="../howto/deployment/asgi/index.html"><span class="doc">ASGI</span></a> instead.</p>
<div class="admonition warning">
<p class="first admonition-title">警告</p>
<p>You will only get the benefits of a fully-asynchronous request stack if you
have <em>no synchronous middleware</em> loaded into your site. If there is a piece
of synchronous middleware, then Django must use a thread per request to
safely emulate a synchronous environment for it.</p>
<p class="last">Middleware can be built to support <a class="reference internal" href="http/middleware.html#async-middleware"><span class="std std-ref">both sync and async</span></a> contexts. Some of Django's middleware is built like
this, but not all. To see what middleware Django has to adapt, you can turn
on debug logging for the <code class="docutils literal notranslate"><span class="pre">django.request</span></code> logger and look for log
messages about <em>&quot;Synchronous middleware ... adapted&quot;</em>.</p>
</div>
<p>In both ASGI and WSGI mode, you can still safely use asynchronous support to
run code concurrently rather than serially. This is especially handy when
dealing with external APIs or data stores.</p>
<p>If you want to call a part of Django that is still synchronous, like the ORM,
you will need to wrap it in a <a class="reference internal" href="#asgiref.sync.sync_to_async" title="asgiref.sync.sync_to_async"><code class="xref py py-func docutils literal notranslate"><span class="pre">sync_to_async()</span></code></a> call. For example:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">asgiref.sync</span> <span class="kn">import</span> <span class="n">sync_to_async</span>

<span class="n">results</span> <span class="o">=</span> <span class="k">await</span> <span class="n">sync_to_async</span><span class="p">(</span><span class="n">Blog</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">get</span><span class="p">,</span> <span class="n">thread_sensitive</span><span class="o">=</span><span class="kc">True</span><span class="p">)(</span><span class="n">pk</span><span class="o">=</span><span class="mi">123</span><span class="p">)</span>
</pre></div>
</div>
<p>You may find it easier to move any ORM code into its own function and call that
entire function using <a class="reference internal" href="#asgiref.sync.sync_to_async" title="asgiref.sync.sync_to_async"><code class="xref py py-func docutils literal notranslate"><span class="pre">sync_to_async()</span></code></a>. For example:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">asgiref.sync</span> <span class="kn">import</span> <span class="n">sync_to_async</span>

<span class="k">def</span> <span class="nf">_get_blog</span><span class="p">(</span><span class="n">pk</span><span class="p">):</span>
    <span class="k">return</span> <span class="n">Blog</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">select_related</span><span class="p">(</span><span class="s1">&#39;author&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">pk</span><span class="o">=</span><span class="n">pk</span><span class="p">)</span>

<span class="n">get_blog</span> <span class="o">=</span> <span class="n">sync_to_async</span><span class="p">(</span><span class="n">_get_blog</span><span class="p">,</span> <span class="n">thread_sensitive</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
</pre></div>
</div>
<p>If you accidentally try to call a part of Django that is still synchronous-only
from an async view, you will trigger Django's
<a class="reference internal" href="#async-safety"><span class="std std-ref">asynchronous safety protection</span></a> to protect your data from
corruption.</p>
<div class="section" id="s-performance">
<span id="performance"></span><h3>Performance<a class="headerlink" href="#performance" title="永久链接至标题">¶</a></h3>
<p>When running in a mode that does not match the view (e.g. an async view under
WSGI, or a traditional sync view under ASGI), Django must emulate the other
call style to allow your code to run. This context-switch causes a small
performance penalty of around a millisecond.</p>
<p>This is also true of middleware. Django will attempt to minimize the number of
context-switches between sync and async. If you have an ASGI server, but all
your middleware and views are synchronous, it will switch just once, before it
enters the middleware stack.</p>
<p>However, if you put synchronous middleware between an ASGI server and an
asynchronous view, it will have to switch into sync mode for the middleware and
then back to async mode for the view. Django will also hold the sync thread
open for middleware exception propagation. This may not be noticeable at first,
but adding this penalty of one thread per request can remove any async
performance advantage.</p>
<p>You should do your own performance testing to see what effect ASGI versus WSGI
has on your code. In some cases, there may be a performance increase even for
a purely synchronous codebase under ASGI because the request-handling code is
still all running asynchronously. In general you will only want to enable ASGI
mode if you have asynchronous code in your project.</p>
</div>
</div>
<div class="section" id="s-async-safety">
<span id="s-id1"></span><span id="async-safety"></span><span id="id1"></span><h2>Async safety<a class="headerlink" href="#async-safety" title="永久链接至标题">¶</a></h2>
<dl class="envvar">
<dt id="envvar-DJANGO_ALLOW_ASYNC_UNSAFE">
<code class="descname">DJANGO_ALLOW_ASYNC_UNSAFE</code><a class="headerlink" href="#envvar-DJANGO_ALLOW_ASYNC_UNSAFE" title="永久链接至目标">¶</a></dt>
<dd></dd></dl>

<p>Certain key parts of Django are not able to operate safely in an async
environment, as they have global state that is not coroutine-aware. These parts
of Django are classified as &quot;async-unsafe&quot;, and are protected from execution in
an async environment. The ORM is the main example, but there are other parts
that are also protected in this way.</p>
<p>If you try to run any of these parts from a thread where there is a <em>running
event loop</em>, you will get a
<a class="reference internal" href="../ref/exceptions.html#django.core.exceptions.SynchronousOnlyOperation" title="django.core.exceptions.SynchronousOnlyOperation"><code class="xref py py-exc docutils literal notranslate"><span class="pre">SynchronousOnlyOperation</span></code></a> error. Note that you
don't have to be inside an async function directly to have this error occur. If
you have called a sync function directly from an async function,
without using <a class="reference internal" href="#asgiref.sync.sync_to_async" title="asgiref.sync.sync_to_async"><code class="xref py py-func docutils literal notranslate"><span class="pre">sync_to_async()</span></code></a> or similar, then it can also occur. This is
because your code is still running in a thread with an active event loop, even
though it may not be declared as async code.</p>
<p>If you encounter this error, you should fix your code to not call the offending
code from an async context. Instead, write your code that talks to async-unsafe
functions in its own, sync function, and call that using
<a class="reference internal" href="#asgiref.sync.sync_to_async" title="asgiref.sync.sync_to_async"><code class="xref py py-func docutils literal notranslate"><span class="pre">asgiref.sync.sync_to_async()</span></code></a> (or any other way of running sync code in
its own thread).</p>
<p>The async context can be imposed upon you by the environment in which you are
running your Django code. For example, <a class="reference external" href="https://jupyter.org/">Jupyter</a> notebooks and <a class="reference external" href="https://ipython.org">IPython</a>
interactive shells both transparently provide an active event loop so that it is
easier to interact with asynchronous APIs.</p>
<p>If you're using an IPython shell, you can disable this event loop by running:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">%</span><span class="n">autoawait</span> <span class="n">off</span>
</pre></div>
</div>
<p>as a command at the IPython prompt. This will allow you to run synchronous code
without generating <a class="reference internal" href="../ref/exceptions.html#django.core.exceptions.SynchronousOnlyOperation" title="django.core.exceptions.SynchronousOnlyOperation"><code class="xref py py-exc docutils literal notranslate"><span class="pre">SynchronousOnlyOperation</span></code></a>
errors; however, you also won't be able to <code class="docutils literal notranslate"><span class="pre">await</span></code> asynchronous APIs. To turn
the event loop back on, run:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">%</span><span class="n">autoawait</span> <span class="n">on</span>
</pre></div>
</div>
<p>If you're in an environment other than IPython (or you can't turn off
<code class="docutils literal notranslate"><span class="pre">autoawait</span></code> in IPython for some reason), you are <em>certain</em> there is no chance
of your code being run concurrently, and you <em>absolutely</em> need to run your sync
code from an async context, then you can disable the warning by setting the
<span class="target" id="index-0"></span><a class="reference internal" href="#envvar-DJANGO_ALLOW_ASYNC_UNSAFE"><code class="xref std std-envvar docutils literal notranslate"><span class="pre">DJANGO_ALLOW_ASYNC_UNSAFE</span></code></a> environment variable to any value.</p>
<div class="admonition warning">
<p class="first admonition-title">警告</p>
<p class="last">If you enable this option and there is concurrent access to the
async-unsafe parts of Django, you may suffer data loss or corruption. Be
very careful and do not use this in production environments.</p>
</div>
<p>If you need to do this from within Python, do that with <code class="docutils literal notranslate"><span class="pre">os.environ</span></code>:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">os</span>

<span class="n">os</span><span class="o">.</span><span class="n">environ</span><span class="p">[</span><span class="s2">&quot;DJANGO_ALLOW_ASYNC_UNSAFE&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="s2">&quot;true&quot;</span>
</pre></div>
</div>
</div>
<div class="section" id="s-async-adapter-functions">
<span id="async-adapter-functions"></span><h2>Async adapter functions<a class="headerlink" href="#async-adapter-functions" title="永久链接至标题">¶</a></h2>
<p>It is necessary to adapt the calling style when calling sync code from an async
context, or vice-versa. For this there are two adapter functions, from the
<code class="docutils literal notranslate"><span class="pre">asgiref.sync</span></code> module: <a class="reference internal" href="#asgiref.sync.async_to_sync" title="asgiref.sync.async_to_sync"><code class="xref py py-func docutils literal notranslate"><span class="pre">async_to_sync()</span></code></a> and <a class="reference internal" href="#asgiref.sync.sync_to_async" title="asgiref.sync.sync_to_async"><code class="xref py py-func docutils literal notranslate"><span class="pre">sync_to_async()</span></code></a>. They
are used to transition between the calling styles while preserving
compatibility.</p>
<p>These adapter functions are widely used in Django. The <a class="reference external" href="https://pypi.org/project/asgiref/">asgiref</a> package
itself is part of the Django project, and it is automatically installed as a
dependency when you install Django with <code class="docutils literal notranslate"><span class="pre">pip</span></code>.</p>
<div class="section" id="s-async-to-sync">
<span id="async-to-sync"></span><h3><code class="docutils literal notranslate"><span class="pre">async_to_sync()</span></code><a class="headerlink" href="#async-to-sync" title="永久链接至标题">¶</a></h3>
<dl class="function">
<dt id="asgiref.sync.async_to_sync">
<code class="descname">async_to_sync</code>(<em>async_function</em>, <em>force_new_loop=False</em>)<a class="headerlink" href="#asgiref.sync.async_to_sync" title="永久链接至目标">¶</a></dt>
<dd></dd></dl>

<p>Takes an async function and returns a sync function that wraps it. Can be used
as either a direct wrapper or a decorator:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">asgiref.sync</span> <span class="kn">import</span> <span class="n">async_to_sync</span>

<span class="k">async</span> <span class="k">def</span> <span class="nf">get_data</span><span class="p">(</span><span class="o">...</span><span class="p">):</span>
    <span class="o">...</span>

<span class="n">sync_get_data</span> <span class="o">=</span> <span class="n">async_to_sync</span><span class="p">(</span><span class="n">get_data</span><span class="p">)</span>

<span class="nd">@async_to_sync</span>
<span class="k">async</span> <span class="k">def</span> <span class="nf">get_other_data</span><span class="p">(</span><span class="o">...</span><span class="p">):</span>
    <span class="o">...</span>
</pre></div>
</div>
<p>The async function is run in the event loop for the current thread, if one is
present. If there is no current event loop, a new event loop is spun up
specifically for the single async invocation and shut down again once it
completes. In either situation, the async function will execute on a different
thread to the calling code.</p>
<p>Threadlocals and contextvars values are preserved across the boundary in both
directions.</p>
<p><a class="reference internal" href="#asgiref.sync.async_to_sync" title="asgiref.sync.async_to_sync"><code class="xref py py-func docutils literal notranslate"><span class="pre">async_to_sync()</span></code></a> is essentially a more powerful version of the
<a class="reference external" href="https://docs.python.org/3/library/asyncio-task.html#asyncio.run" title="(在 Python v3.9)"><code class="xref py py-func docutils literal notranslate"><span class="pre">asyncio.run()</span></code></a> function in Python's standard library. As well
as ensuring threadlocals work, it also enables the <code class="docutils literal notranslate"><span class="pre">thread_sensitive</span></code> mode of
<a class="reference internal" href="#asgiref.sync.sync_to_async" title="asgiref.sync.sync_to_async"><code class="xref py py-func docutils literal notranslate"><span class="pre">sync_to_async()</span></code></a> when that wrapper is used below it.</p>
</div>
<div class="section" id="s-sync-to-async">
<span id="sync-to-async"></span><h3><code class="docutils literal notranslate"><span class="pre">sync_to_async()</span></code><a class="headerlink" href="#sync-to-async" title="永久链接至标题">¶</a></h3>
<dl class="function">
<dt id="asgiref.sync.sync_to_async">
<code class="descname">sync_to_async</code>(<em>sync_function</em>, <em>thread_sensitive=True</em>)<a class="headerlink" href="#asgiref.sync.sync_to_async" title="永久链接至目标">¶</a></dt>
<dd></dd></dl>

<p>Takes a sync function and returns an async function that wraps it. Can be used
as either a direct wrapper or a decorator:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">asgiref.sync</span> <span class="kn">import</span> <span class="n">sync_to_async</span>

<span class="n">async_function</span> <span class="o">=</span> <span class="n">sync_to_async</span><span class="p">(</span><span class="n">sync_function</span><span class="p">,</span> <span class="n">thread_sensitive</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
<span class="n">async_function</span> <span class="o">=</span> <span class="n">sync_to_async</span><span class="p">(</span><span class="n">sensitive_sync_function</span><span class="p">,</span> <span class="n">thread_sensitive</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>

<span class="nd">@sync_to_async</span>
<span class="k">def</span> <span class="nf">sync_function</span><span class="p">(</span><span class="o">...</span><span class="p">):</span>
    <span class="o">...</span>
</pre></div>
</div>
<p>Threadlocals and contextvars values are preserved across the boundary in both
directions.</p>
<p>Sync functions tend to be written assuming they all run in the main
thread, so <a class="reference internal" href="#asgiref.sync.sync_to_async" title="asgiref.sync.sync_to_async"><code class="xref py py-func docutils literal notranslate"><span class="pre">sync_to_async()</span></code></a> has two threading modes:</p>
<ul class="simple">
<li><code class="docutils literal notranslate"><span class="pre">thread_sensitive=True</span></code> (the default): the sync function will run in the
same thread as all other <code class="docutils literal notranslate"><span class="pre">thread_sensitive</span></code> functions. This will be the
main thread, if the main thread is synchronous and you are using the
<a class="reference internal" href="#asgiref.sync.async_to_sync" title="asgiref.sync.async_to_sync"><code class="xref py py-func docutils literal notranslate"><span class="pre">async_to_sync()</span></code></a> wrapper.</li>
<li><code class="docutils literal notranslate"><span class="pre">thread_sensitive=False</span></code>: the sync function will run in a brand new thread
which is then closed once the invocation completes.</li>
</ul>
<div class="admonition warning">
<p class="first admonition-title">警告</p>
<p class="last"><code class="docutils literal notranslate"><span class="pre">asgiref</span></code> version 3.3.0 changed the default value of the
<code class="docutils literal notranslate"><span class="pre">thread_sensitive</span></code> parameter to <code class="docutils literal notranslate"><span class="pre">True</span></code>. This is a safer default, and in
many cases interacting with Django the correct value, but be sure to
evaluate uses of <code class="docutils literal notranslate"><span class="pre">sync_to_async()</span></code> if updating <code class="docutils literal notranslate"><span class="pre">asgiref</span></code> from a prior
version.</p>
</div>
<p>Thread-sensitive mode is quite special, and does a lot of work to run all
functions in the same thread. Note, though, that it <em>relies on usage of</em>
<a class="reference internal" href="#asgiref.sync.async_to_sync" title="asgiref.sync.async_to_sync"><code class="xref py py-func docutils literal notranslate"><span class="pre">async_to_sync()</span></code></a> <em>above it in the stack</em> to correctly run things on the
main thread. If you use <code class="docutils literal notranslate"><span class="pre">asyncio.run()</span></code> or similar, it will fall back to
running thread-sensitive functions in a single, shared thread, but this will
not be the main thread.</p>
<p>The reason this is needed in Django is that many libraries, specifically
database adapters, require that they are accessed in the same thread that they
were created in. Also a lot of existing Django code assumes it all runs in the
same thread, e.g. middleware adding things to a request for later use in views.</p>
<p>Rather than introduce potential compatibility issues with this code, we instead
opted to add this mode so that all existing Django sync code runs in the same
thread and thus is fully compatible with async mode. Note that sync code will
always be in a <em>different</em> thread to any async code that is calling it, so you
should avoid passing raw database handles or other thread-sensitive references
around.</p>
</div>
</div>
</div>


          </div>
        </div>
      </div>
      
        
          <div class="yui-b" id="sidebar">
            
      <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
        <div class="sphinxsidebarwrapper">
  <h3><a href="../contents.html">Table of Contents</a></h3>
  <ul>
<li><a class="reference internal" href="#">Asynchronous support</a><ul>
<li><a class="reference internal" href="#async-views">Async views</a><ul>
<li><a class="reference internal" href="#performance">Performance</a></li>
</ul>
</li>
<li><a class="reference internal" href="#async-safety">Async safety</a></li>
<li><a class="reference internal" href="#async-adapter-functions">Async adapter functions</a><ul>
<li><a class="reference internal" href="#async-to-sync"><code class="docutils literal notranslate"><span class="pre">async_to_sync()</span></code></a></li>
<li><a class="reference internal" href="#sync-to-async"><code class="docutils literal notranslate"><span class="pre">sync_to_async()</span></code></a></li>
</ul>
</li>
</ul>
</li>
</ul>

  <h4>上一个主题</h4>
  <p class="topless"><a href="external-packages.html"
                        title="上一章">External packages</a></p>
  <h4>下一个主题</h4>
  <p class="topless"><a href="../howto/index.html"
                        title="下一章">操作指南</a></p>
  <div role="note" aria-label="source link">
    <h3>本页</h3>
    <ul class="this-page-menu">
      <li><a href="../_sources/topics/async.txt"
            rel="nofollow">显示源代码</a></li>
    </ul>
   </div>
<div id="searchbox" style="display: none" role="search">
  <h3>快速搜索</h3>
    <div class="searchformwrapper">
    <form class="search" action="../search.html" method="get">
      <input type="text" name="q" />
      <input type="submit" value="转向" />
      <input type="hidden" name="check_keywords" value="yes" />
      <input type="hidden" name="area" value="default" />
    </form>
    </div>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
        </div>
      </div>
              <h3>Last update:</h3>
              <p class="topless">7月 23, 2021</p>
          </div>
        
      
    </div>

    <div id="ft">
      <div class="nav">
    &laquo; <a href="external-packages.html" title="External packages">previous</a>
     |
    <a href="index.html" title="Using Django" accesskey="U">up</a>
   |
    <a href="../howto/index.html" title="操作指南">next</a> &raquo;</div>
    </div>
  </div>

      <div class="clearer"></div>
    </div>
  </body>
</html>